package com.itheima.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.constant.MessageConstant;
import com.itheima.entity.PageResult;
import com.itheima.entity.QueryPageBean;
import com.itheima.entity.Result;
import com.itheima.mapper.MenuMapper;
import com.itheima.mapper.UserMapper;
import com.itheima.pojo.Menu;
import com.itheima.pojo.User;
import com.itheima.service.UserService;
import com.itheima.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.transaction.annotation.Transactional;


import java.util.List;
import java.util.*;

@Transactional
@Service(interfaceClass = UserService.class)
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MenuMapper menuMapper;

    @Override
    public List<Map<String, Object>> findAllHealthManager() {
        List<Map<String, Object>> list = userMapper.findAllHealthManager();
        return list;
    }

    @Override
    public Integer findByMemberId(Integer memberId) {
        Integer id = userMapper.findByMemberId(memberId);
        return id;
    }

    //通过用户名名查询用户详情(包括角色列表,和权限列表)
    public User findByUsername(String username) {

        return userMapper.findDetailByUsername(username);
    }

    /* ========================================================================================================== */

    /**
     * 1.根据用户名查询用户对应的菜单
     *
     * @param username
     * @return
     */
    @Override
    public List<Menu> getMenuByUsername(String username) {

        List<Menu> resultMenu = new ArrayList<>();
        // 1.获取所有的菜单列表
        List<Menu> dbMenuList = menuMapper.getAllMenus(username);

        Map<Integer, Menu> menuMap = new HashMap<>();
        if (dbMenuList != null && dbMenuList.size() > 0) {
            for (Menu menu : dbMenuList) {
                menuMap.put(menu.getId(), menu);
            }

            // 组合菜单列表
            for (Menu menu : dbMenuList) {
                // 将获取到的所有菜单当成子菜单
                Menu node = menu;

                // 判断是否是根节点
                if (node.getParentMenuId() == null) {
                    // 是根节点 ====> 添加到集合中
                    resultMenu.add(menu);
                } else {
                    // 不是根节点 ====> 寻找每个节点的根节点
                    Menu root = menuMap.get(node.getParentMenuId());
                    root.getChildren().add(node);
                }
            }
        }
        return resultMenu;
    }

    /**
     * 2.用户列表分页+模糊查询
     *
     * @param pageBean
     * @return
     */
    @Override
    public PageResult getUserList(QueryPageBean pageBean) throws Exception {
        PageHelper.startPage(pageBean.getCurrentPage(), pageBean.getPageSize());
        Page<Map<String, Object>> page = userMapper.getListByConditon(pageBean.getQueryString());

        if (page != null && page.getTotal() > 0) {
            for (Map<String, Object> map : page) {
                String createDate = DateUtils.parseDate2String((Date) map.get("createDate"));
                map.put("createDate", createDate);
            }
        }
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * 3.添加系统用户信息
     *
     * @param roleIds
     * @param user
     */
    @Override
    public Result create(Integer[] roleIds, User user) {
        user.setCreateDate((java.sql.Date) new Date());
        user.setPassword(BCrypt.hashpw(user.getPassword(), BCrypt.gensalt()));
        userMapper.createUser(user);

        Integer userId = user.getId();
        if (roleIds == null || roleIds.length == 0) {
            return new Result(true, "添加用户成功,没有为用户分配角色");
        }

        // 维护关联关系
        this.addUserAndRole(roleIds, userId);

        return new Result(true, MessageConstant.ADD_USER_SUCCESS);
    }

    /**
     * 4.根据用户id查询用户信息以及关联的角色信息
     *
     * @param id
     * @return
     */
    @Override
    public Map<String, Object> getUserById(Integer id) {
        User user = userMapper.getUserById(id);
        Map<String, Object> result = new HashMap<>();
        result.put("user", user);

        // 获取关联关系
        List<Integer> roleIds = userMapper.getRoleIdsByUserId(id);
        result.put("roleIds", roleIds);
        return result;
    }

    /**
     * 5.更新用户数据
     *
     * @param roleIds
     * @param user
     * @return
     */
    @Override
    public Result update(Integer[] roleIds, User user) {
        userMapper.update(user);
        if (roleIds == null || roleIds.length == 0) {
            return new Result(true, "更新用户信息成功,未分配角色信息");
        }

        // 获取关联关系
        Integer userId = user.getId();
        List<Integer> dbRoleIds = userMapper.getRoleIdsByUserId(userId);

        if (dbRoleIds == null || dbRoleIds.size() == 0) {
            this.addUserAndRole(roleIds, userId);
            return new Result(true, MessageConstant.EDIT_USER_SUCCESS);
        }

        // 根据用户id删除关联关系
        userMapper.deleteUserAndRoleByUserId(userId);

        // 重新添加关联关系
        this.addUserAndRole(roleIds, userId);
        return new Result(true, MessageConstant.EDIT_USER_SUCCESS);
    }

    /**
     * 6.删除用户数据
     *
     * @param id
     */
    @Override
    public void deleteById(Integer id) {
        List<Integer> dbRoleIds = userMapper.getRoleIdsByUserId(id);

        if (dbRoleIds == null || dbRoleIds.size() == 0) {
            userMapper.deleteById(id);
            return;
        }

        // 根据用户id删除关联关系
        userMapper.deleteUserAndRoleByUserId(id);
        userMapper.deleteById(id);
    }

    /**
     * 7.用户登录次数统计
     */
    @Override
    public void loginStatistics(String username) {
        userMapper.loginStatistics(username);
    }


    /**
     * 扩展方法:维护关联关系
     *
     * @param roleIds
     * @param userId
     */
    private void addUserAndRole(Integer[] roleIds, Integer userId) {
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        params.put("roleIds", roleIds);
        userMapper.addUserAndRole(params);
    }

}
